home *** CD-ROM | disk | FTP | other *** search
-
- /***********************************************************************/
-
- /* File KLINE.C - Comms-line handling procedures for RML Kermit;
- Chris Kennington RML. 9th July 1985. */
-
- #define DEFS1 1
- #define DEFS2 1
-
- #include "stdio.h"
- #include "b:kext.h"
-
-
- /* local globals for nextin/nextout */
- static int fuzzy = 20000; /* arbitry value */
- static int ret;
- static char dummy, typout;
- static char comerr[] = "Comms err %x";
- static char enter[] = " Enter %s for mainframe:\r> ";
-
-
- connect() /* keyboard/screen to comms line relay */
- /* Reads keyboard and transmits to line; reads line and outputs to
- screen; checks comms line for error conditions. */
- {
- char c, cn, conn;
- static char pager = 0, *data[5];
- int in;
-
- printmsg("Connecting you to remote mainframe ... ");
- keyconn(); /* make arrows valid */
- outc(NL);
- kmode = CONN;
- while (kmode == CONN) { /* until stopped */
- if (keyget(&c) != 0) {
- if (echo != 0)
- outc(c);
- cn = 100;
- while (cn-- > 0)
- if (s4put(1,&c) > 0)
- break;
- if (cn == 0)
- bell();
- }
- if ( (in = s4get7(1,&data)) == 1 ) {
- #ifndef MPUZ80
- if (*data != LF)
- #endif
- outfc(*data);
- }
- else if (in != 0) {
- outc(NL);
- printmsg("Comms error code %x; ", in);
- while (s4test() == in)
- ;
- }
- } /* end switch */
- /* broken out by changing kmode */
- return;
- } /* End of connect() */
-
-
-
-
- flushinput()
- /* Dump all pending input to clear stacked up NAK's. */
- {
- char rubbish[11];
-
- while (s4get(10,rubbish) > 0)
- ;
- } /* end of flushinput */
-
-
-
- inctry() /* increment tries & pkt-# */
- /* used by both recieve & send routines */
- {
- oldtry = numtry;
- numtry = 0;
- n = (n+1)%64;
- return;
- } /* end of inctry() */
-
-
-
- /* Line-I/O Routines for sending/receiving files */
-
- static nextab() /* set abort-flag if CTLC */
- {
- if (dummy == CTLC) { /* treat ctlc as abort */
- printmsg("Abort transfer");
- if (confirm() == TRUE)
- abtflag = 1;
- dummy = 0;
- }
- return;
- } /* end of nextab() */
-
- nextin(ic) /* next char from line */
- /* strips parity bit if !image; handles fuzzy timeout;
- returns 0, but 1 if either abtflag or nakflag has been set */
- char *ic;
- {
- int r;
-
- abtflag = nakflag = 0;
- One:
- while ( (ret = (image) ? s4get(1,ic) : s4get7(1,ic)) == 0 ) {
- keyget(&dummy);
- nextab();
- if ( (abtflag+nakflag) != 0 )
- return(1);
- if (--fuzzy == 0) { /* timer expired */
- nakflag = 1;
- ++timouts;
- if (list == 1)
- outc('T');
- if (list > 2)
- txtout("\rDbg: Timeout.");
- return(1);
- } }
- while (ret < 0) { /* error */
- printmsg(comerr,ret);
- while ( (r = (image) ? s4get(1,ic) : s4get7(1,ic)) == ret) {
- keyget(&dummy);
- if ( (abtflag+nakflag) != 0 )
- return(1);
- }
- if (r == 0)
- goto One;
- ret = r;
- }
- if (list > 4)
- outc(*ic);
- if (*ic == SOH)
- fuzzy = fuzz[env]; /* fuzzy timer re-set on SOH only */
- return(abtflag+nakflag);
- } /* end of nextin() */
-
-
-
- nextout(c) /* next char to line */
- /* returns 0, but 1 if either abtflag or nakflag has been set */
- char c;
- {
- int r;
-
- abtflag = nakflag = 0;
- One:
- while ( (ret = s4put(1,&c)) == 0 ) {
- keyget(&dummy);
- nextab();
- if ( (abtflag+nakflag) != 0 )
- return(1);
- }
- while (ret < 0) { /* error */
- printmsg(comerr,ret);
- while ( (r = s4put(1,&c)) == ret) {
- keyget(&dummy);
- if ( (abtflag+nakflag) != 0 )
- return(1);
- }
- if (r == 0)
- goto One;
- ret = r;
- }
- if (list > 4)
- outc(c);
- keyget(&dummy);
- return(abtflag+nakflag);
- } /* end of nextout() */
-
-
-
- char rpack(len,num,data) /* Read a Packet */
- /* If !image, nextin() has stripped the parity bit. */
- int *len, *num; /* Packet length, number */
- char *data; /* Packet data */
- {
- int i, done; /* Data character number, loop exit */
- char t, /* Current input character */
- cchksum, /* Our (computed) checksum */
- rchksum; /* Checksum received from other host */
- static int oldnum = 63;
-
- Top:
- fuzzy = fuzz[env]; /* set timer */
- t = type = 0; /* could be garbage */
- *len = 0; /* in case timeout */
- while (t != SOH) if (nextin(&t) != 0) {
- type = 'T';
- goto Flag;
- }
-
- done = FALSE; /* Got SOH, init loop */
- while (!done) { /* Loop to get a packet */
- if (nextin(&t) != 0) /* Get length character */
- break;
- cchksum = t; /* Start the checksum */
- if (t == SOH)
- continue; /* Resynchronize if SOH */
- t &= 0x7f; /* 7-bit protocol char */
- if ( (*len = unchar(t)-3) < 0 ) /* Character count */
- return(FALSE); /* protect against bad length */
- if (nextin(&t) != 0) /* Get packet-number character */
- break;
- cchksum = cchksum + t; /* Update checksum */
- t &= 0x7f; /* 7-bit protocol char */
- if (t == SOH)
- continue; /* Resynchronize if SOH */
- *num = unchar(t); /* Packet number */
- if (*num == oldnum)
- ++dupes; /* its a duplicate */
- else
- oldnum = *num;
- vtout(LOCSEQ,t|0x80);
-
- if (nextin(&t) != 0) /* Get packet-type character */
- break;
- cchksum = cchksum + t; /* Update checksum */
- t &= 0x7f; /* 7-bit protocol char */
- if (t == SOH)
- continue; /* Resynchronize if SOH */
- if ( (type = t) == 'N' ) {
- ++naxin; /* its a NAK */
- if (list == 1)
- outc('N');
- }
- if (type == typout)
- goto Top; /* its an echo */
- vtout(LOCIN,type);
-
- for (i=0; i<*len; i++) { /* The data itself, if any */
- if (nextin(&t) != 0) /* Get data character */
- break;
- cchksum = cchksum + t; /* Update checksum */
- data[i] = t; /* Put it in the data buffer */
- t &= 0x7f; /* 7-bit char */
- if (t == SOH) break; /* stop if SOH */
- }
- if (t == SOH)
- continue; /* Resynchronize if SOH */
- if ( (nakflag+abtflag) != 0 )
- break;
- data[*len] = 0; /* Mark the end of the data */
-
- if (nextin(&t) != 0) /* Get checksum character */
- break;
- rchksum = unchar(t); /* Convert to numeric */
- done = TRUE; /* Got checksum, done */
- }
- flushinput(); /* discard anything stacked */
- if ( (list > 3) && ( (nakflag+abtflag) == 0 ) ) { /* Display */
- outc(CR);
- printf(" Packet in: type %c, num %d, len%d;",type,*num,*len);
- outc(CR);
- if (*len != 0) {
- data[*len] = 0;
- printf(" data: \"%s\";",data);
- outc(CR);
- } }
-
- Flag: /* check for user abort or nak */
- vtout(LOCIN,type|0x80); /* inverse of type */
- if (nakflag != 0)
- return(FALSE); /* cause NAK to be sent */
- if (abtflag != 0) {
- abtflag = 0;
- return('A'); /* cause ABORT */
- }
- /* Fold in bits 7,8 to compute */
- cchksum = (((cchksum&0300) >> 6)+cchksum)&077; /* final checksum */
-
- if (cchksum == rchksum) {
- if (type == 'D')
- blockmv(oldpkt,data,*len); /* copy for reference */
- return(type); /* OK return */
- }
- ++badcrcs; /* count bad checksum */
- if (list == 1)
- outc('C');
- else if (list > 2)
- txtout(" Bad checksum ");
- return(FALSE);
- } /* end of rpack() */
-
-
-
- servsend(type) /* send command to server-Kermit etc. */
- char type;
- {
- int *len, *num;
- char pkt;
-
- switch(type) {
-
- case RMSV: /* Server Commands */
- pkt = 'K'; /* packet-type */
- goto Rmcont;
-
- case RMH: /* OS Commands */
- pkt = 'C'; /* packet-type */
- Rmcont:
- txtout(" Calling mainframe ... ");
- if (parex() == 0) { /* exchange parameters */
- printmsg("Mainframe Kermit seems dead ");
- kmode = KERM;
- break;
- }
- else forever {
- printmsg(enter,"message");
- if (keyline(packet) == 0) {
- kmode = CMND;
- break;
- }
- printmsg("Telling mainframe ... ");
- recsw(type,pkt);
- }
- break;
-
- case GET: /* fetch files */
- printf(inform);
- printmsg(enter,"filenames");
- if (keyline(packet) == 0)
- kmode = KERM;
- else {
- vtline(LOCMODE,rcvng);
- state = kmode = GET;
- }
- break;
-
- case SEND: /* send files */
- vtline(LOCMODE,sendf);
- kmode = SEND;
- break;
-
- case BYE: /* logout from mainframe */
- spack('G',n,1,"L"); /* generic logout */
- kmode = KERM;
- outc(SP);
- txtout(trying);
- rpack(&len,&num,recpkt);
- if (len != 0) {
- recpkt[*len] = 0;
- printmsg("%s %s",mainsays,recpkt);
- }
- break;
-
- case LOGO: /* cancel mainframe Kermit */
- spack('G',n,1,"F"); /* try "Finish" */
- txtout(dots);
- if (rpack(&len,&num,recpkt) != 'Y') /* synchronize */
- spack('E',0,strlen(errmsg),errmsg);
- vtline(LOCMODE,connto);
- kmode = CONN;
- break;
-
- case QUIT: /* cancel (local) Kermit */
- kermkill(1);
-
- case MAIN: /* back to top level */
- kmode = KERM;
- break;
-
- } /* end switch */
- return;
- } /* end of servsend() */
-
-
-
- setbaud() /* set line-speed from spdcode */
- {
- vtline(LOCSPEED+3," ");
- vtline(LOCSPEED,spval[spdcode]);
- s4speed(spdcode);
- return;
- } /* end of setbaud() */
-
-
-
- setpar() /* set parity from parity */
- {
- commode &= 0xfcff; /* remove parity bits */
- commode |= (int)parity * 256; /* substitute new */
- s4set(commode,comctrl);
- return;
- } /* end of setpar() */
-
-
-
- spack(type,num,len,data) /* Send a Packet */
- char type, *data;
- int num, len;
- {
- int i; /* Character loop counter */
- char c, chksum;
- register char *bufp; /* Buffer pointer */
- static int cumnum = 0;
-
- if (list > 3) { /* Display outgoing packet */
- outc(CR);
- printf(" Packet out: type %c, num %d, len %d:",type,num,len);
- outc(CR);
- if (len != 0) {
- data[len] = 0;
- printf(" data: \"%s\";",data);
- outc(CR);
- } }
-
- vtout(LOCOUT,type);
- vtout(LOCSEQ,tochar(n));
- sprintf(work,"%d =",cumnum++);
- vtline(LOCPKTS,work);
-
- for (i=1; i<=pad; i++)
- if (nextout(&padchar) != 0) /* padding */
- return;
- bufp = work; /* buffer pointer */
- *bufp++ = SOH;
- *bufp++ = tochar(len+3);
- chksum = tochar(len+3);
- *bufp++ = tochar(num);
- chksum += tochar(num);
- typout = *bufp++ = type;
- chksum += type;
-
- for (i=0; i<len; i++) { /* for all data characters */
- *bufp++ = c = data[i];
- chksum += c;
- }
- chksum = (((chksum&0300) >> 6)+chksum)&077; /* Compute final checksum */
- *bufp++ = tochar(chksum);
- *bufp++ = eol; /* Extra-packet line terminator */
- *bufp = CR; /* & CR for safety */
- len = bufp-work+1;
- bufp = work;
- while (len-- > 0)
- if (nextout(*bufp++) != 0)
- break;
- vtout(LOCOUT,type|0x80); /* inverse of type */
- if (netslow) /* discard any buffered dupes */
- flushinput();
- return;
- } /* end of spack() */
-
-
-
- /********************** End of KLINE.C **************************/
-
-